import R from "@common/type/response";
import { getSysUserByUsername } from "@common/service/sys_user";
import { NextApiRequest, NextApiResponse } from "next";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
import { getRedisClient } from "@common/database/redis";
import { redisService } from "@common/utils/redis";
import IpUtils from "@common/utils/ip";
import { parseUserAgent } from "@common/utils/user-agent";
import { SysLogininforService } from "@common/service/sys_logininfor";
import { SysPermissionService } from "@common/service/sys_permissions";

export default function handler(req: NextApiRequest, res: NextApiResponse) {
    login(req, res);
}


async function saveLogininfor(req: NextApiRequest, res: NextApiResponse, username: string, status: string, msg: string = '') {
    // 记录登录失败信息
    try {
        const userAgent = req.headers['user-agent'] as string;
        const { browser, os } = parseUserAgent(userAgent);
        const ip = IpUtils.getIp(req);
        let logininfor = {
            user_name: username,
            ipaddr: ip,
            login_location: ip,
            browser: browser,
            os: os,
            status: status, // 1表示失败
            msg: status === '0' ? '登录成功' : '登录失败',
            login_time: new Date()
        }
        if (msg && msg !== '') {
            logininfor.msg = msg;
        }
        await SysLogininforService.createLogininfor(logininfor);
    } catch (error) {
        console.error('记录登录失败信息失败:', error);
    }
}

async function login(req: NextApiRequest, res: NextApiResponse) {
    const reqBody = req.body;
    if (!reqBody || !reqBody.username || !reqBody.password) {
        R.error(res, 'username or password is required');
    }
    const user = await getSysUserByUsername(reqBody.username) as any;
    if (!user) {
        await saveLogininfor(req, res, reqBody.username, '1', '用户名或密码错误');
        R.error(res, 'user not found');
    }
    // 密码加密
    const password = reqBody.password;
    // 验证密码
    const isValid = await bcrypt.compare(password, user.password);
    if (!isValid) {
        await saveLogininfor(req, res, reqBody.username, '1', '用户名或密码错误');
        return res.status(401).json({ message: "用户名或密码错误" });
    }
    // 生成一个 v4 UUID
    const uuid = crypto.randomUUID();
    console.log(uuid); 
    // 生成token
    const token = jwt.sign(
        {
            id: user.user_id,
            uuid: uuid
        },
        process.env.JWT_SECRET || '',
        {
            expiresIn:'30d'
        }
    );
    // user 去掉密码
    user.password = undefined;

    // 解析header user-agent
    const userAgent = req.headers['user-agent'] as string;
    const { browser, os } = parseUserAgent(userAgent);
    const device = userAgent.match(/Mobile|Tablet|Desktop/i)?.[0] || 'Unknown';
    const ip = IpUtils.getIp(req);

    let loginUser:LoginUser = {
        userId: user.user_id,
        userName: user.user_name,
        userMobile: user.phonenumber,
        token: token,
        browser: browser,
        os: os,
        device: device,
        ip: ip,
        loginTime: new Date().toISOString(),
        loginLocation: ip,
        user: user
    }
    
    try {
        loginUser.permissions = await SysPermissionService.getUserPermissions(user.user_id);
    } catch (error) {
        console.error(error);
        loginUser.permissions = [];
    }

    // 将uuid保存到redis
    await redisService.set('login_tokens:'+uuid, loginUser, 30 * 24 * 60 * 60);
    
    await saveLogininfor(req, res, user.user_name, '0', '登录成功');
    
    // 返回用户信息和 token
    R.success(res, { user, token });
}
